// SPDX-License-Identifier: MPL-2.0
// Original code from [https://asterinas.github.io/book/ostd/a-100-line-kernel.html], modified by Yao Yu.
// Copyright (c) 2025 Yao Yu
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#![no_std]
#![deny(unsafe_code)]

// 检查，正确就跳过，错误就返回Err("")
macro_rules! check {
    ($e:expr) => {
        if !$e {
            return Err("");
        }
    };
    ($e:expr, $msg: expr) => {
        if !$e {
            return Err($msg);
        }
    };
}


extern crate alloc;
use alloc::{sync::Arc, boxed::Box, vec::Vec};

mod arch;
mod context;
mod cpu;
mod error;
mod kernel_thread;
mod link_app;
mod thread;
mod prelude;
mod process;
mod sched;
mod syscall;
mod utils;
use kernel_thread::*;
use link_app::get_user_programs;
use sched::sched_init;
use thread::*;

/// The kernel's boot and initialization process is managed by OSTD.
/// After the process is done, the kernel's execution environment
/// (e.g., stack, heap, tasks) will be ready for use and the entry function
/// labeled as `#[ostd::main]` will be called.
#[ostd::main]
pub fn main() {
    let files = get_user_programs();
    // 随机数生成器初始化
    utils::random::init();
    // 调度器初始化
    sched_init();
    thread::init();
    let mut fivec = Vec::new();
    for fi in files {
        fivec.push(fi);
    }

    let kernel_data = KernelInfo{
        files: fivec,
    };
    let init_task = Arc::new_cyclic(|weak_task| {
        let thread = Arc::new(Thread::new(weak_task.clone(), Some(Box::new(kernel_data))));
        create_init_thread(thread)
    });
    let init_thread = init_task.as_thread().unwrap();
    init_thread.run();
}
